package networking;

import gameStates.absGamesStates.AbsIngameState;
import interfaces.menu.joinGame.gamesTable.GamesTableWidget;
import interfaces.menu.joinGame.gamesTable.PlayerWidget;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import logic.common.game.Game;
import logic.common.player.Player;
import logic.common.team.Fraction;
import logic.common.team.Team;
import main.GameCycle;

public class ServerInfoThread extends Thread {
	
	public static final int INFO_PORT = 9141;
	
	private ServerSocket serverSocket;
	
	private AbsIngameState ingameState;
	
	private boolean isAlive;
	
	public ServerInfoThread(AbsIngameState ingameState) {
		super();
		this.ingameState = ingameState;
		
		isAlive = true;
		
		try {
			serverSocket = new ServerSocket(INFO_PORT, 0, InetAddress.getLocalHost());
			serverSocket.setSoTimeout(500);
		} catch(Exception e) { e.printStackTrace(); }
	}
	
	@Override
	public void run() {
		while(isAlive) {
			Socket socket = null;
			ObjectInputStream ois = null;
			ObjectOutputStream oos = null;
			
			try {
				socket = serverSocket.accept();
				
				ois = new ObjectInputStream(socket.getInputStream());
				int input = ois.readInt();
				
				oos = new ObjectOutputStream(socket.getOutputStream());
				
				if(input == GameInfoCreator.REQUEST) {
					GamesTableWidget w = createGameInfo();
					if(w != null) oos.writeObject(w);
					else oos.writeObject("tooearly");
				} else oos.writeObject("wrongrequest");
				
				oos.flush();
			} catch(Exception e) {
			} finally {
				if(ois != null) {
					try { ois.close(); }
					catch(Exception e) { e.printStackTrace(); }
				}
				if(oos != null) {
					try { oos.close(); }
					catch(Exception e) { e.printStackTrace(); }
				}
				if(socket != null) {
					try { socket.close(); }
					catch(Exception e) { e.printStackTrace(); }
				}
			}
		}
		
		if(serverSocket != null) {
			try {
				serverSocket.close();
				
				long startTime = System.currentTimeMillis();
				while(!serverSocket.isClosed() 
				&& System.currentTimeMillis() - startTime <= 5000) {}
			} catch(Exception e) { e.printStackTrace(); }
		}
		
		ingameState = null;
		serverSocket = null;
	}
	
	private GamesTableWidget createGameInfo() {
		if(ingameState == null || ingameState.getRootBlock() == null 
		|| ingameState.getGame() == null || ingameState.getGame().getGameCycle() == null) return null;
		GameCycle cycle = ingameState.getGame().getGameCycle();
		
		ArrayList<PlayerWidget> playerWidgets = new ArrayList<PlayerWidget>();
		Game game = ingameState.getGame();
		getPlayerWidgets(game.getTeamA(), playerWidgets);
		getPlayerWidgets(game.getTeamB(), playerWidgets);
		
		try {
			GamesTableWidget widget = new GamesTableWidget(cycle, playerWidgets);
			return widget;
		} catch(Exception e) { e.printStackTrace(); }
		return null;
	}
	
	private void getPlayerWidgets(Team team, List<PlayerWidget> playerWidgets) {
		for(Player player : team.getAllPlayers()) {
			Fraction fraction = team.getFraction();
			PlayerWidget widget = new PlayerWidget(player.getName(), fraction, player.getKills());
			playerWidgets.add(widget);
		}
	}
	
	public void killThread() { isAlive = false; }
}